package cn.edu.ccut.refactor;

import java.text.MessageFormat;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;

import cn.edu.ccut.util.RefactorXMLParse;


/**
 * 
 * @author Bai Yucheng 2008-1-10
 * 
 */
public class MoveSaturnFileChange extends Change {
	private IFile saturnFile;
	private IContainer fDestContainer;
	private final IPath fResourcePath;
	private final IPath fDestinationPath;

	public MoveSaturnFileChange(IFile iFile, IContainer icontainer) {
		saturnFile = iFile;
		fDestContainer = icontainer;
		fResourcePath = getResourcePath(iFile);
		fDestinationPath = getResourcePath(fDestContainer);
	}

	public RefactoringStatus isValid(IProgressMonitor iprogressmonitor)
			throws CoreException {
		return null;
	}

	public final Change perform(IProgressMonitor iprogressmonitor)
			throws CoreException {
		String s;
		iprogressmonitor.beginTask(getName(), 2);
		String parentName = fDestContainer.getParent().getName();
		String newPkgName = fDestContainer.getName();
		if (saturnFile.getFileExtension().equals("saturndata")) {    //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
			if (parentName.endsWith("module") || parentName.endsWith("Module")) {   //$NON-NLS-1$ //$NON-NLS-2$
				newPkgName = parentName + "/" + newPkgName;  //$NON-NLS-1$
			}
			RefactorXMLParse.renameSelfName(saturnFile, newPkgName, 1);
			refreshOutputDir("\\" + saturnFile.getProject().getName() + "\\");   //$NON-NLS-1$ //$NON-NLS-2$
		}	
		s = getResource().getName();
		boolean flag = deleteIfAlreadyExists(new SubProgressMonitor(
				iprogressmonitor, 1), s);
		if (flag) {
			getResource().move(getDestinationPath(s), getReorgFlags(),
					new SubProgressMonitor(iprogressmonitor, 1));
		}
		iprogressmonitor.done();
		return null;
	}
	
	private static void refreshOutputDir(String outputdir) {
		IResource bufferRes = findMember(ResourcesPlugin.getWorkspace().getRoot(), outputdir);

		if (bufferRes != null && bufferRes.isAccessible()) {
			try {
				bufferRes.refreshLocal(IResource.DEPTH_INFINITE, null);
			} catch (CoreException e) {
			}
		}
	}

	private static IResource findMember(IWorkspaceRoot root, String path) {
		Path pathOrNull = pathOrNull(path);
		if (pathOrNull == null)
			return null;
		return root.findMember(pathOrNull);
	}

	private static Path pathOrNull(String p) {
		if (p == null || p.trim().length() == 0) {
			return null;
		} else {
			return new Path(p);
		}
	}

	private boolean deleteIfAlreadyExists(IProgressMonitor iprogressmonitor,
			String s) throws CoreException {
		iprogressmonitor.beginTask("", 1);  //$NON-NLS-1$
		IResource iresource = getDestination().findMember(s);
		if (iresource == null)
			return true;
		if (!iresource.exists())
			return true;
		IResource iresource1 = getResource();
		if (iresource1 == null)
			return false;
		if (equalInWorkspaceOrOnDisk(iresource1, iresource))
			return false;
		String s1 = MessageFormat.format(Messages.getString("MoveSaturnFileChange.8"),  //$NON-NLS-1$
				new String[] { s });
		MessageDialog messagedialog = new MessageDialog(null,
				Messages.getString("MoveSaturnFileChange.9"), null, s1, 3, new String[] { IDialogConstants.YES_LABEL,  //$NON-NLS-1$
						IDialogConstants.NO_LABEL }, 0);
		boolean flag = messagedialog.open() == 0;
		if (!flag)
			return false;
		if (iresource instanceof IFile)
			((IFile) iresource).delete(false, true, new SubProgressMonitor(
					iprogressmonitor, 1));
		else
			Assert.isTrue(false);
		return true;
	}

	public static boolean equalInWorkspaceOrOnDisk(IResource iresource,
			IResource iresource1) {
		if (iresource == null || iresource1 == null)
			return false;
		if (iresource.equals(iresource1))
			return true;
		IPath ipath = iresource.getLocation();
		IPath ipath1 = iresource1.getLocation();
		if (ipath == null || ipath1 == null)
			return false;
		else
			return ipath.equals(ipath1);
	}

	static IPath getResourcePath(IResource iresource) {
		return iresource.getFullPath().removeFirstSegments(
				ResourcesPlugin.getWorkspace().getRoot().getFullPath()
						.segmentCount());
	}

	static IFolder getFolder(IPath ipath) {
		return ResourcesPlugin.getWorkspace().getRoot().getFolder(ipath);
	}

	static IFile getFile(IPath ipath) {
		return ResourcesPlugin.getWorkspace().getRoot().getFile(ipath);
	}

	protected IPath getDestinationPath(String s) {
		return getDestination().getFullPath().append(s);
	}

	protected IResource getResource() {
		return getFile(fResourcePath);
	}

	IContainer getDestination() {
		return getFolder(fDestinationPath);
	}

	protected int getReorgFlags() {
		return 34;
	}

	public String getName() {
		return Messages.getString("MoveSaturnFileChange.10") + fResourcePath.toString() + Messages.getString("MoveSaturnFileChange.11") + fDestinationPath.toString();   //$NON-NLS-1$ //$NON-NLS-2$
	}

	public Object getModifiedElement() {
		return saturnFile;
	}

	@Override
	public void initializeValidationData(IProgressMonitor pm) {
	}
}